Главная arrow Форум  
27.04.2024 г.
Главная
Проекты
Статьи
Начинающим
Архив новостей
Ссылки
Контакты
Поиск
Файлы
Форум
Карта сайта
Авторизация





Забыли пароль?
Ещё не зарегистрированы? Регистрация
Поддержи наш сайт!
Через WebMoney

 R785211844650
 Z210696637574
 E368177590409

Форум ARV Research
Добро пожаловать, Гость
Пожалуйста Вход или Регистрация.
Забыли пароль?
Мелкие вопросы (1 просматривает)
_GEN_GOTOBOTTOM Ответить

TOPIC: Мелкие вопросы

#7330
ARV (Администратор)
Администратор
Постов: 2386
graph
В ответ на: Мелкие вопросы 26.03.2012 22:56 Репутация: 176  
FreshMan писал(а):
ну вот, сбылась мечта идиота, я написал примитивную прогу для своих будущих часов......ужас...
Не стыдно не знать, стыдно не учиться
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7331
FreshMan (Пользователь)
Специалист
Постов: 177
graphgraph
В ответ на: Мелкие вопросы 26.03.2012 23:11 Репутация: 1  
почему ?
не ......, ну я согласен что это далеко не идеал, но.........
а что вы можете предложить ?
Experience is the name everyone give to his mistakes.
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7332
FreshMan (Пользователь)
Специалист
Постов: 177
graphgraph
В ответ на: Мелкие вопросы 27.03.2012 00:07 Репутация: 1  
уже немного модернизировал
Code:

 #include <mega8.h> #include <delay.h> #define kn_sec_reset PINC.0  // на 0 пин порта С подключена кнопка сброса секунд #define kn_min_up PINC.1    //  на 1 пин порта С подключена кнопка инкремента минут #define anod_sec_l (PORTD|=(1<<4)) #define anod_sec_h (PORTD|=(1<<5)) #define anod_min_l (PORTD|=(1<<6)) #define anod_min_h (PORTD|=(1<<7)) unsigned int x; unsigned char secmin,i; unsigned char number[4];               // в этом массиве мы будем хранить десятки и единици секунд и минут //unsigned char znak[4]={16,32,64,128};  // в этом массиве мы храним номер анода индикатора  определенного разряда               interrupt [TIM0_OVFvoid timer0_ovf_isr(void)// Timer 0 срабатывает каждую мс { // Reinitialize Timer 0 value TCNT0=0x83; // Place your code here if(++x==1000) {sec++; x=0;}; } interrupt [TIM1_COMPAvoid timer1_compa_isr(void)// Timer 1 срабатывает каждые 5мс { PORTD=0; switch (i)      {     case 0:PORTD=number[i]; anod_sec_l; break;     case 1:PORTD=number[i]; anod_sec_h; break;     case 2:PORTD=number[i]; anod_min_l; break;     case 3:PORTD=number[i]; anod_min_h; break;     };    if (++i==4)i=0; } void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  // State6=T State5=T State4=T State3=T State2=T State1=P State0=P  PORTC=0x03; DDRC=0x00; // Port D initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out  // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0  PORTD=0x00; DDRD=0xFF; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 125,000 kHz TCCR0=0x02; TCNT0=0x83; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 125,000 kHz // Mode: CTC top=OCR1A // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x0A; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x02; OCR1AL=0x71; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x11; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // Global enable interrupts #asm("sei") while (1)       {        number[0]=sec%10;  //в массив записываем остаток от деления преременной sec        number[1]=sec/10// в массив записываем целую часть от деления преременной sec         number[2]=min%10// в массив записываем остаток от деления преременной min        number[3]=min/10// в массив записываем целую часть от деления преременной min        if (sec==60) {sec=0min++;};        if (min==60min=0;        if (kn_sec_reset==0) {delay_ms(10);sec=0; while(kn_sec_reset==0){}; delay_ms(10);};        if (kn_min_up==0) {delay_ms(10);min++; while(kn_min_up==0){}; delay_ms(10);};       }; }

Experience is the name everyone give to his mistakes.
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7333
ARV (Администратор)
Администратор
Постов: 2386
graph
В ответ на: Мелкие вопросы 27.03.2012 08:27 Репутация: 176  
ужас в том, что я потратил столько времени, чтобы попытаться вас научить нормальному стилю программирования - и все впустую. жалко потраченного времени. невнятные переменные, тем более глобальные, вывод снова в куче с обработкой данных... про сам непродуманный алгоритм я пока молчу - это естественноо для начинающего, но стиль... я ведь объяснял....
Не стыдно не знать, стыдно не учиться
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7334
FreshMan (Пользователь)
Специалист
Постов: 177
graphgraph
В ответ на: Мелкие вопросы 27.03.2012 18:50 Репутация: 1  
и все впустую.
простите,но дерзну с вами не согласится............., ничто в этой жизни не проходит безследно........., притчу о блудном сыне помните ? насчет переменных я ваш урок усвоил, просто зачастую я немогу придумать им внятные имена, например, переменная i, которая фигурирует у меня в программе так и осталась без внятного имени, ну незнаю я как ее толково назвать, поэтому и юзаю примитивные имена........, может подскажете вы ?
переделал прогу, но часы стали идти ОЧЕНЬ медленно, где может быть моя ошибка ....?
Code:

 #include <mega8.h> #include <delay.h> #define kn_sec_reset PINC.0  // на 0 пин порта С подключена кнопка сброса секунд #define kn_min_up PINC.1    //  на 1 пин порта С подключена кнопка инкремента минут #define anod_sec_l (PORTD|=(1<<4)) #define anod_sec_h (PORTD|=(1<<5)) #define anod_min_l (PORTD|=(1<<6)) #define anod_min_h (PORTD|=(1<<7)) unsigned int var; unsigned char secmin,i; unsigned char number[4];               // в этом массиве мы будем хранить десятки и единици секунд и минут //unsigned char znak[4]={16,32,64,128};  // в этом массиве мы храним номер анода индикатора  определенного разряда               interrupt [TIM0_OVFvoid timer0_ovf_isr(void)// Timer 0 срабатывает каждую мс { // Reinitialize Timer 0 value TCNT0=0x83; // Place your code here if(++var==1000) {sec++; var=0;}; } interrupt [TIM1_COMPAvoid timer1_compa_isr(void)// Timer 1 срабатывает каждые 5мс { PORTD=0; switch (i)      {     case 0:PORTD=number[i]; anod_sec_l; break;     case 1:PORTD=number[i]; anod_sec_h; break;     case 2:PORTD=number[i]; anod_min_l; break;     case 3:PORTD=number[i]; anod_min_h; break;     };    if (++i==4)i=0; } void mathematics(unsigned char secmin) { number[0]=sec%10;  //в массив записываем остаток от деления преременной sec number[1]=sec/10// в массив записываем целую часть от деления преременной sec  number[2]=min%10// в массив записываем остаток от деления преременной min number[3]=min/10// в массив записываем целую часть от деления преременной min } void main(void) { // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  // State6=T State5=T State4=T State3=T State2=T State1=P State0=P  PORTC=0x03; DDRC=0x00; // Port D initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out  // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0  PORTD=0x00; DDRD=0xFF; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 125,000 kHz TCCR0=0x02; TCNT0=0x83; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 125,000 kHz // Mode: CTC top=OCR1A // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: On // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x0A; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x02; OCR1AL=0x71; OCR1BH=0x00; OCR1BL=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x11; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // Global enable interrupts #asm("sei") while (1)       {        mathematics (min,sec);        if (sec==60) {sec=0min++;};        if (min==60min=0;        if (kn_sec_reset==0) {delay_ms(10);sec=0; while(kn_sec_reset==0){}; delay_ms(10);};        if (kn_min_up==0) {delay_ms(10);min++; while(kn_min_up==0){}; delay_ms(10);};       }; }

Experience is the name everyone give to his mistakes.
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7335
ARV (Администратор)
Администратор
Постов: 2386
graph
В ответ на: Мелкие вопросы 27.03.2012 21:24 Репутация: 176  
видите ли... раз вы не можете придумать осмысленное название переменной, значит, и на самом деле в ее наличии нет никакого смысла! не скажу, что ВСЕ БЕЗ ИСКЛЮЧЕНИЯ переменные должны быть поименованы со смыслом, но тем не менее.

беда не в том, что переменная названа "i", а в том, что она вынесена в область глобальных переменных! в масштабе вашей программы нет для нее места, так что же она делает на виду у всех?! ее задача - где-то в недрах функции, обеспечивающей индикацию (прерывании то есть) обозначать номер текущего разряда. вам ведь в главном цикле не важно, какой именно в данный момент времени индикатор светится? значит, и переменная для этого не должна быть видима в главном цикле. я веду к тому, что она должна быть ЛОКАЛЬНОЙ переменной!
Code:

 interrupt [TIM1_COMPAvoid timer1_compa_isr(void)// Timer 1 срабатывает каждые 5мс { static unsigned char i 0; PORTD=0; switch (i)      {     case 0:PORTD=number[i]; anod_sec_l; break;     case 1:PORTD=number[i]; anod_sec_h; break;     case 2:PORTD=number[i]; anod_min_l; break;     case 3:PORTD=number[i]; anod_min_h; break;     };    if (++i==4)i=0; }

вот и все! но не совсем.
посмотрите на эту функцию, а конкретно - на оператор switch. скажите, чем ПРИНЦИПИАЛЬНО отличаются все 4 варианта case в этом операторе? ДА НИЧЕМ! они делают абсолютно однотипные действия, и отличаются только конкретным разрядом порта, который активируют! смотрите:
Code:

 interrupt [TIM1_COMPAvoid timer1_compa_isr(void)// Timer 1 срабатывает каждые 5мс { static unsigned char mask 1<<4;  static unsigned char position 0;      PORTD=0;     mask <<= 1;     position++;     if(position >= IND_CNT){         mask 1<<4;         position 0;     }     PORTD number[position] | mask; }

логично? понимаете, в чем разница? снова обращаю ваше внимание на замену волшебного числа 4 на константу IND_CNT - помните, почему так надо делать?

об остальном позже
Не стыдно не знать, стыдно не учиться
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7336
ARV (Администратор)
Администратор
Постов: 2386
graph
В ответ на: Мелкие вопросы 27.03.2012 22:00 Репутация: 176  
теперь об остальном. matematics - это что за функция? не смотря на название, намекающее, что внутри идут какие-то вычисления, это функция ДЛЯ ВЫВОДА ЧИСЛА. вопрос знатокам - почему она названа математикой, а не выводом? 6 балло за правильный ответ! но это пустяк. не пустяк, что в этой функции вы снова не подумали о том, что разрядов на вашем индикаторе может быть не только 4. ваш алгоритм предусматривает работу с 4 индикаторами, а если их будет 5 или 6 - придется все переделывать. но зачем? ведь АЛГОРИТМ для разделения числа на разряды не зависит от числа этих разрядов! вот здесь я специально рассказывал о том, как это надо делать!

наконец, почему счет времени у вас ведется в основном цикле?! это совершенно неправильно! счет времени должен быть точным, а основной цикл занимается всем остальным, к точности чего требований не предъявляется. и даже в вашем случае не совсем понятен алгоритм счета времени - как-то шиворот навыворот записано простое: если секунд прошло 60, обнулить секунды и увеличить минуты, затем проверить: если минут прошло 60, то обнулить минуты и увеличить часы. затем проверить: если часов прошло 24, то обнулить часы и.... и т.д. в виде кода это очень логично записывается так:
Code:

 sec++; if(sec >= 60){    sec 0;    min++;    if(min >= 60){       min 0;       hour++;    } }

Не стыдно не знать, стыдно не учиться
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7337
ARV (Администратор)
Администратор
Постов: 2386
graph
В ответ на: Мелкие вопросы 27.03.2012 22:02 Репутация: 176  
аналогично с работой с кнопками - все, о чем я вам толковал, все проигнорировано но повторять уже не буду: либо вы на самом деле хотите прислушиваться к моим советам, либо не хотите - это ваш выбор.
Не стыдно не знать, стыдно не учиться
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7338
FreshMan (Пользователь)
Специалист
Постов: 177
graphgraph
В ответ на: Мелкие вопросы 27.03.2012 23:22 Репутация: 1  
все замечания принимаю безпрекословно, каюсь и обещаю исправиться
давайте по порядку:
логично? понимаете, в чем разница?
логика у вас железная !!!
разница, как на меня, в том, что ваш код построен намного красивей и в нем нету "повторяемости"........, я же так понимаю ?
на замену волшебного числа 4 на константу IND_CNT - помните, почему так надо делать?
это для того чтобы в программе небыло непонятных чисел, а все носило осмысленные названия, дабы и через 100 лет наши потомки смогли уразуметь что мы им хотели сказать ....., ведь так ?
константу IND_CNT нужно обявлять в начале проги ?
вот так: # define IND_CNT 4
осмелюсь переспросить, ваш код
Code:

  interrupt [TIM1_COMPAvoid timer1_compa_isr(void)// Timer 1 срабатывает каждые 5мс { static unsigned char mask 1<<4;  static unsigned char position 0;      PORTD=0;     mask <<= 1;     position++;     if(position >= IND_CNT){         mask 1<<4;         position 0;     }     PORTD number[position] | mask; }


разве не правильнее бы было его записать так?
не ошиблись ли вы ?
Code:

 interrupt [TIM1_COMPAvoid timer1_compa_isr(void)// Timer 1 срабатывает каждые 5мс { static unsigned char mask 1<<4;  static unsigned char position 0;      PORTD=0;     if(position >= IND_CNT){mask 1<<4position 0;}     PORTD number[position] | mask;     mask <<= 1;     position++; }


если нет, тогда я буду расписывать каждую строчку как я ее разумею.
Experience is the name everyone give to his mistakes.
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#7339
ARV (Администратор)
Администратор
Постов: 2386
graph
В ответ на: Мелкие вопросы 28.03.2012 08:28 Репутация: 176  
FreshMan писал(а):
логика у вас железная !!!
разница, как на меня, в том, что ваш код построен намного красивей и в нем нету "повторяемости"........, я же так понимаю ?

логика - она или железная, или отсутствует. красота - это следствие логичности кода. главное, в чем логика проявляется - это в максимальном соответствии того, что написано, тому, что определяет алгоритм. ведь алгоритм, если он правильно составлен, должен быть НЕЗАВИСИМ от количества обрабатываех им данных - в данном случае от количества разрядов на индикаторе: мы допускаем, что общие аноды(или катоды) индикатора идут в порту ПОСЛЕДОВАТЕЛЬНО, и составляем алгоритм так, что его реализация на Си остается НЕИЗМЕННОЙ для 1,2,3,4 и т.д. до 8 разрядов. вот в этом логика и красота.

когда вы решаете задчу, решать ее надо, как в алгебре - в виде формулы, а не в вид конечного числа. формула позволяет получить быстро ответ для любых исходных данных, а если решать в числах - всякий раз придется пересчитывать все-все-все. это совет.

это для того чтобы в программе небыло непонятных чисел, а все носило осмысленные названия, дабы и через 100 лет наши потомки смогли уразуметь что мы им хотели сказать ....., ведь так ?потомкам наверняка будет начхать на наши с вами коды... смысл констант в том, что назначение ей значения производится В ОДНОМ МЕСТЕ ПРОГРАММЫ, и затем, когда вы это значение меняете - всюду, где эта константа применялась, все меняется БЕЗ ОШИБОК. количество индикаторов у вас будет влиять на обработчик прерывания, на размер массива под выводимые символы, на алгоритм перевода числа в символы - всюду эта константа одна и та же. вы сделали вместо 4 ее значение 6 - и все участки кода СРАЗУ и ПРАВИЛЬНО стали обрабатывать эту ситуацию! Вы сами себе гарантируете, что число ошибок в вашей программе будет стремиться к минимуму! да и читать код вам будет проще.

что касается записи кода, то нет принципиальной разницы, что делать раньше - изменять положение выводимой позиции на индикатор, а затем обновлять содержимое индикатора, или наоборот. но в вашем варианте есть 2 участка, выполняющих одно и то же - это минус. беда не в том, что код повторяется, беда в том, что повторяется смысловй участок алгоритма - это черевато проблемами и ошибками, т.к. в случае чего вам придется менять код в двух местах и отслеживать, когла это надо и не надо.

как и ранее, логика должна быь железной: для достижения цели должен быть избран кратчайший путь, ведущий к успеху. простой пример: вам нужно подмести пол и пообедать. вариантов может быть два:
1. помыть руки, пообедать, подмести пол, помыть руки.
2. подмести пол, помыть руки, пообедать.
как видите, мытье рук - необходимо в обоих случаях: перед приемом пищи и после того, как запачкали руки. расположив действия в правильном логическом порядке, вы исключаете лишнее мытье рук. и в вашем алгоритме все, что можт делаться один раз, должно делаться один раз.
Не стыдно не знать, стыдно не учиться
  Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
_GEN_GOTOTOP Ответить
© Copyright 2007 Best of Joomla, Работает на FireBoardполучить последние сообщения прямо на Ваш рабочий стол